package com.xcity.game.http.gm;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;

import naga.x.App;
import naga.x.event.Event;
import naga.x.event.EventListener;
import naga.x.service.Service;
import naga.x.service.ServiceException;

import com.xcity.db.entity.Mail;
import com.xcity.db.entity.Player;
import com.xcity.game.event.GameEvents;
import com.xcity.game.mail.MailService;
import com.xcity.game.player.PlayerService;

public class GMService implements Service, EventListener {
	
	// 给所有玩家的系统邮件
	private List<PendingMail> pendingPublicMails = new ArrayList<PendingMail>(2);
	
	protected static class PendingMail {
		Mail mail;
		Set<Long> sent; // 已发送过该邮件的玩家
		PendingMail(Mail mail) {
			this.mail = mail;
			this.sent = new ConcurrentSkipListSet<Long>();
		}
	}

	@Override
	public void startup() throws ServiceException {
		App.getApp().getEventManager().register(this);
	}

	@Override
	public void shutdown() throws ServiceException {
	}

	@Override
	public String getId() {
		return getClass().getName();
	}

	@Override
	public int[] getEventTypes() {
		return new int[] { GameEvents.EVENT_PLAYER_LOGIN };
	}

	@Override
	public void handleEvent(Event event) {
		Player player = event.getParameter();
		for (int i = 0, size = pendingPublicMails.size(); i < size; i++) {
			sendPublic(player, pendingPublicMails.get(i));
		}
	}
	
	public void sendMail(Mail mail) {
		if (mail.getDestId() != 0) {
			sendPrivate(mail);
		} else {
			PendingMail pm = new PendingMail(mail);
			pendingPublicMails.add(pm);
			broadcastMail(pm);
		}
	}
	
	private void sendPrivate(Mail mail) {
		App.getApp().getServiceManager().get(MailService.class).sendMail(mail);
	}
	
	private void broadcastMail(PendingMail mail) {
		Collection<Player> vals = App.getApp().getServiceManager().get(PlayerService.class).getOnlinePlayers();
		for (Player player : vals) {
			sendPublic(player, mail);
		}
	}
	
	private void sendPublic(Player player, PendingMail mail) {
		Long id = Long.valueOf(player.getId());
		if (mail.sent.contains(id)) {
			return;
		}
		mail.sent.add(id);
		Mail dup = new Mail(mail.mail);
		dup.setDestId(player.getId());
		App.getApp().getServiceManager().get(MailService.class).sendMail(dup);
	}

}
